#include "pcrChartItem.h"

PCRChartItem::PCRChartItem(QWidget* parent){

    this->setParent(parent);
    _axisX = new QValueAxis(this);
    _axisY = new QValueAxis(this);
    this->legend()->hide();

    this->addAxis(_axisX, Qt::AlignBottom);
    this->addAxis(_axisY, Qt::AlignLeft);
    this->updateRange(0,1,0,1);

    initColor();

#ifdef Q_OS_ANDROID
    int fontId = QFontDatabase::addApplicationFont(":/FontStyle/AlibabaPuHuiTi-3-55-Regular.ttf");
    if (fontId != -1) {
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
        if (!fontFamilies.isEmpty()) {
            QString familyName = fontFamilies.first();
            QFont font(familyName, 12);
            this->setFont(font);
            _axisX->setLabelsFont(font);
            _axisY->setLabelsFont(font);
            _axisX->setTitleFont(font);
            _axisY->setTitleFont(font);
        }
    }
#endif

}

void PCRChartItem::setDefaultColor(QVector<QColor> colorList){

    DebugLog::funcStart(DEBUG_CONTEXT);

    _colorMode = 0;
    for(int i = 0; i < std::min(colorList.size(), _defaultColor.size()); i ++){
        _defaultColor[i] = colorList[i];
    }
    for(auto iter = _series.begin(); iter != _series.end(); iter ++){
        iter.value()->setPen(getPen(iter.key(), _state[iter.key()]));
    }
    DebugLog::funcEnd(DEBUG_CONTEXT);
}
void PCRChartItem::setDefaultColor_posi(QMap<QString, QColor> colorList){
    DebugLog::funcStart(DEBUG_CONTEXT);
    _colorMode = 1;
    _defaultColor_posi = colorList;
    for(auto iter = _series.begin(); iter != _series.end(); iter ++){
        if(!_state.contains(iter.key()))    continue;
        iter.value()->setPen(getPen(iter.key(), _state[iter.key()]));
    }
    DebugLog::funcEnd(DEBUG_CONTEXT);

}

void PCRChartItem::initColor(){
    DebugLog::funcStart(DEBUG_CONTEXT);
    _colorMode = 0;
    _defaultColor.clear();
    _defaultColor.push_back(COLOR1);
    _defaultColor.push_back(COLOR2);
    _defaultColor.push_back(COLOR3);
    _defaultColor.push_back(COLOR4);
    DebugLog::funcEnd(DEBUG_CONTEXT);
}



void PCRChartItem::updateCurve(){
//    DebugLog::funcStart(DEBUG_CONTEXT);
    QString name;
    int changeTimes = 0;
    for(auto iter = _state.begin(); iter != _state.end(); iter ++){

        name = iter.key();
        if(_lastState[name] != _state[name]){
            _lastState[name] = _state[name];
            if(_state[name] == NORM || _state[name] == BOLD){
                _series[name]->setPen(getPen(name, _state[name]));
                _series[name]->show();
            }else{
                _series[name]->hide();
            }
            changeTimes ++;
        }
    }
//    DebugLog::funcEnd(DEBUG_CONTEXT);
}

void PCRChartItem::updateRange(){
//    DebugLog::funcStart(DEBUG_CONTEXT);
    _xmax = std::max(2.0, _xmax);
    _axisX->setRange(1, _xmax);
    _axisX->setTickCount(std::min(16.0, _xmax));
    _axisX->setLabelFormat("%.0f");

    if(_ymax < 10){
        _axisY->setLabelFormat("%.1f");
        _ymax = std::max(1.0, std::ceil(_ymax));
        _ymin = std::floor(_ymin);
        _axisY->setTickCount(_ymax-_ymin+1);
        _axisY->setRange(_ymin, _ymax);
    }
    else{

        _axisY->setLabelFormat("%.0f");
        int ynum = std::floor(log10(_ymax));
        int ybase = pow(10, ynum-1);
        _ymax = std::ceil(_ymax / ybase) * ybase;

        _axisY->setRange(0, _ymax);
        _axisY->setTickCount(11);
    }
//    DebugLog::funcEnd(DEBUG_CONTEXT);
}

void PCRChartItem::updateRange(double xmin, double xmax, double ymin, double ymax){
    _axisX->setRange(xmin, xmax);
    _axisY->setRange(ymin, ymax);
}

void PCRChartItem::appendCurve(QString name, QVector<QPointF> pointList, QString type, ShowState state, int scatterType){


    for(int i = 0; i < pointList.size(); i ++){
        // 更新坐标轴参数
        _xmax = std::max(pointList[i].x(), _xmax);
        _xmin = std::min(pointList[i].x(), _xmin);
        _ymax = std::max(pointList[i].y(), _ymax);
        _ymin = std::min(pointList[i].y(), _ymin);
    }
    if(_series.contains(name)){
        _series[name]->replace(pointList);
        return;
    }


    if(type == "spline"){
        QSplineSeries* ts = new QSplineSeries;
        ts->setName(name);
        ts->setPen(getPen(name, state));
        _series.insert(name, ts);
    }else if(type == "scatter"){
        QScatterSeries* ts = new QScatterSeries;
        ts->setName(name);
        ts->setPen(getPen(name, state));
        ts->setMarkerSize(10);
        ts->setBrush(QBrush(ts->pen().color()));
        ts->setMarkerShape(scatterType==0 ? QScatterSeries::MarkerShapeCircle : QScatterSeries::MarkerShapeRectangle);
        _series.insert(name, ts);
    }else if(type == "line"){
        QLineSeries* ts = new QLineSeries;
        ts->setName(name);
        ts->setPen(getPen(name, state));
        _series.insert(name, ts);
    }
    _series[name]->replace(pointList);
    _lastState[name] = state;
    _state[name] = state;

    // 关联至chart
    this->addSeries(_series[name]);
    _series[name]->attachAxis(_axisX);
    _series[name]->attachAxis(_axisY);

}


QPen PCRChartItem::getPen(QString name, ShowState state){
    QPen pen;

    switch (_colorMode) {
    case 0:
        if(name.contains("FAM")){
            pen.setColor(_defaultColor[0]);
        }else if(name.contains("VIC")){
            pen.setColor(_defaultColor[1]);
        }else if(name.contains("ROX")){
            pen.setColor(_defaultColor[2]);
        }else if(name.contains("CY5")){
            pen.setColor(_defaultColor[3]);
        }
        break;
    case 1:
        // 直接算名字里的序号吧……
        if(!name.contains("_")){
            pen.setColor(QColor());
        }else{
            QString posi = name.split("_")[1];
            if(!_defaultColor_posi.contains(posi)){
                if(name.contains("FAM")){
                    pen.setColor(_defaultColor[0]);
                }else if(name.contains("VIC")){
                    pen.setColor(_defaultColor[1]);
                }else if(name.contains("ROX")){
                    pen.setColor(_defaultColor[2]);
                }else if(name.contains("CY5")){
                    pen.setColor(_defaultColor[3]);
                }
            }else{
                pen.setColor(_defaultColor_posi[posi]);
            }
        }

        break;
    }

    if(state == NORM){
        pen.setWidth(lineWidthNorm);
    }if(state == BOLD || name.contains("THR")){
        pen.setWidth(lineWidthBold);
    }

    return pen;
}



void PCRChartItem::changeCurveState(QString name, ShowState state){
    if(!_series.contains(name)){
        return;
    }
    _state[name] = state;
}

void PCRChartItem::changeCurveState(const QStringList &names, ShowState state){
    foreach(QString name, names){
        if(!_series.contains(name)){
            continue;
        }
        _state[name] = state;
    }
}

void PCRChartItem::changeCurveState_reg(QString name, ShowState state){
    for(auto iter = _state.begin(); iter != _state.end(); iter ++){
        if(iter.key().contains(name)){
            iter.value() = state;
        }
    }
}
